package com.zhoujun.utils;/*
 * Copyright zhoujun 2021 Wicrenet, Inc. All rights reserved.
 */

import com.zhoujun.function.ConsumeFunction;
import org.apache.commons.collections.CollectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 【合并两个list的数据】
 *
 * @author zhoujun
 * Created on 2021/9/29 10:22
 */
public class DataMergeUtils {

    private DataMergeUtils(){}

    /**
     * 【 合并数据 】
     *
     * @author zhoujun
     * @date 2021/9/29 17:02
     * @param listPrimary 主数据集合
 * @param classifierPrimary 主数据关联字段
 * @param followList 从数据集合
 * @param classifierFollow 从数据关联字段
 * @param consumeFunction 主数据配置从数据集合接口
     * @return java.util.List<R>
     **/
    public static <R,T,K> List<R> merge(List<R> listPrimary, Function<R,K> classifierPrimary, List<T> followList, Function<T,K> classifierFollow , ConsumeFunction<R,T> consumeFunction){
        //ColumnUtil.getName(classifierFollow);

        Map<K, List<T>> collect = followList.stream().collect(Collectors.groupingBy(classifierFollow));
        listPrimary.forEach(r->{
            K key =  Objects.requireNonNull(classifierPrimary.apply(r), "element cannot be mapped to a null key");
            consumeFunction.accept(r, collect.get(key));
            
        });
        return listPrimary;
    }

    /**
     * 【 合并数据 】
     *
     * @author zhoujun
     * @date 2021/9/29 17:02
     * @param listPrimary 主数据集合
     * @param classifierPrimary 主数据关联字段
     * @param followList 从数据集合
     * @param classifierFollow 从数据关联字段
     * @return java.util.List<R>
     **/
    public static <R,T,K> List<R> mergeDefault(List<R> listPrimary, Function<R,K> classifierPrimary, List<T> followList, Function<T,K> classifierFollow ){
        if(CollectionUtils.isEmpty(listPrimary) || CollectionUtils.isEmpty(followList)){
            return listPrimary;
        }
        long startTime = System.currentTimeMillis();
        String classNameFollow= followList.get(0).getClass().getName().replaceAll(".*\\.","");//去掉 包名.

        Map<K, List<T>> collect = followList.stream().collect(Collectors.groupingBy(classifierFollow));
        listPrimary.forEach(r->{
            K key =  Objects.requireNonNull(classifierPrimary.apply(r), "element cannot be mapped to a null key");
            Method method = null;
            try {
                method = r.getClass().getDeclaredMethod("set"+classNameFollow+"List", List.class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            try {
                method.invoke(r, collect.get(key));//set方法，没有返回值，此处invoke是 null
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        });
        long endTime = System.currentTimeMillis();
        System.out.println("解析数据用时："+(endTime - startTime));
        return listPrimary;
    }
}
